package config

import (
	"fmt"
	"github.com/natefinch/lumberjack"
	cron "github.com/robfig/cron/v3"

	"github.com/rs/zerolog"
	"os"
)

type Config  struct {
	AppName string  `toml:"app_name"`
	*Http  `toml:"http"`
	*Grpc `toml:"grpc"`
	*GrpcServer `toml:"grpc-server"`
	*Logs `toml:"logs"`
	*CrontabStatus `toml:"crontab"`

}

func  NewConfigDefault() *Config {
	return &Config{
		AppName: "test",
		Http: NewHttpDefault(),
		Grpc: NewGrpcDefault(),
		GrpcServer: NewGrpcServerDefault(),
		Logs: NewDefaultLogs(),
		CrontabStatus: NewDefaultCrontabStatus(),
	}
}
func (c *Config) String() string { 
	return fmt.Sprintf("AppName: %s \nHttp:%s \nGrpcServer:%s \nlogs: %s\ncrontab: %s\n",c.AppName,c.Http,C.GrpcServer,c.Logs,c.CrontabStatus)
}


type Grpc struct{
	Host string `json:"host" toml:"host"`
	Port string  `json:"port" toml:"port"`
}

type GrpcServer struct{
	Host string `json:"host" toml:"host"`
	Port string  `json:"port" toml:"port"`
}

func NewGrpcServerDefault() *GrpcServer {
	return &GrpcServer{
		Host: "localhost",
		Port: "9090",
	}
}
type Http struct {
	Host string `json:"host" toml:"host"`
	Port string  `json:"port" toml:"port"`
}

func NewHttpDefault() *Http {
	return &Http{
		Host: "localhost",
		Port: "8081",
	}
}
func (h *Http) String() string {
	return fmt.Sprintf(h.Host + ":" + h.Port)
}

func (h *Http) GetAddress() string {
	return fmt.Sprintf(h.Host + ":" + h.Port)
}


func NewGrpcDefault() *Grpc {
	return &Grpc{
		Host: "localhost",
		Port: "8091",
	}
}

func (g  *Grpc)String() string {
	return  fmt.Sprintf(g.Host + ":" + g.Port)
}
func (g  *Grpc)GetAddress() string {
	return  fmt.Sprintf(g.Host + ":" + g.Port)
}

func (g  *GrpcServer)String() string {
	return  fmt.Sprintf(g.Host + ":" + g.Port)
}

func (g  *GrpcServer)GetAddress() string {
	return  fmt.Sprintf(g.Host + ":" + g.Port)
}
type Logs  struct{
	LogLevel  string  `json:"loglevel" toml:"loglevel"`
	LogPath  string `json:"logpath" toml:"logpath"`
	MaxSize int `json:"maxsize" toml:"maxsize"`
	MaxBackups int   `json:"maxbackups" toml:"maxbackups"`
	MaxAge int `json:"maxage" toml:"maxage"`
	Logger zerolog.Logger
	FnList  []*os.File
}

func NewDefaultLogs()  *Logs{
	return  &Logs{
		LogLevel: "info",
		LogPath: "./log/",
		FnList: make([]*os.File, 0),
		MaxSize: 10,
		MaxBackups: 3,
		MaxAge: 10,
	}
}

func (l *Logs)  String() string {
	return  fmt.Sprintf("logpath:%s loglevel:%s  maxsize:%d maxbackups:%d maxage:%d\n",l.LogPath,l.LogLevel,l.MaxSize,l.MaxBackups,l.MaxAge)
}


func (l *Logs) Getlog(name string) zerolog.Logger {
	if _, err := os.Stat(l.LogPath); os.IsNotExist(err) {
        os.MkdirAll(l.LogPath, 0644)
    }
	appLog := &lumberjack.Logger{
		Filename:   fmt.Sprintf("%s/%s.log",l.LogPath,name), // 日志文件路径
		MaxSize:    l.MaxSize,                 // 单个日志文件最大大小（以 MB 为单位）
		MaxBackups: l.MaxBackups,                 // 保留旧文件的最大数量
		MaxAge:     l.MaxAge,                 // 旧文件保留的最大天数
		Compress:   true,              // 是否启用压缩
	}
	// l.FnList = append(l.FnList, appLog.)
	if l.LogLevel=="info" {
		l.Logger = zerolog.New(appLog).Level(zerolog.InfoLevel).With().Caller().Timestamp().Logger()
	} else if  l.LogLevel=="warning" {
		l.Logger = zerolog.New(appLog).Level(zerolog.WarnLevel).With().Caller().Timestamp().Logger()
	} else if   l.LogLevel=="error"  {
		l.Logger = zerolog.New(appLog).Level(zerolog.ErrorLevel).With().Caller().Timestamp().Logger()
	}else if   l.LogLevel=="debug"{
		l.Logger = zerolog.New(appLog).Level(zerolog.DebugLevel).With().Caller().Timestamp().Logger()
	}else {
		l.Logger = zerolog.New(appLog).Level(zerolog.InfoLevel).With().Caller().Timestamp().Logger()
	}
	return  l.Logger
}

type CrontabStatus  struct{
	Enable  bool  `json:"enable" toml:"enable"`
	Crontab  *cron.Cron  
	Spec  string  `toml:"spec"`
}

func NewDefaultCrontabStatus()  *CrontabStatus{
	return  &CrontabStatus{
		Enable: false,
		Crontab: cron.New(),
	}
}

func (C *CrontabStatus) String() string{
	return  fmt.Sprintf("enable:%p   spec:%s",&C.Enable,C.Spec)
}